#include "compute.h"


stackN * nums; stackC * symbol;
extern char * EshowD;
extern int EshowLen, showState;
extern int underlen;

int * handlenum(uint8_t * data, int len, int i){
	int num = 0;
	while(i < len && '0' <= data[i] && data[i] <= '9')
	{
		num *= 10;
		num += data[i] - '0';
		i++;
	}
	int temp[2] = {num, i};
	int * res = temp;
	return res;
}

int calculate(){
	char c = StackCPop(symbol);
	int b = StackNPop(nums);
	int a = StackNPop(nums);
	int res = -1;
	switch(c)
	{
		case '+': res = a + b;break;
		case '-': res = a - b;break;
		case '*': res = a * b;break;
		case '/': res = a / b;break;
	}
	return res;
}



void handData(uint8_t * data, int len)
{
	int flag = 0;
	EshowD[EshowLen++] = '?';
	
	for(int i = 0; i < len;)
	{
		while(i < len && data[i] >= '0' && data[i] <= '9')
		{
			EshowD[EshowLen++] = data[i++];
			flag = 1;
		}
		if(flag == 1)			EshowD[EshowLen++] = '?', flag = 0;
		if(i < len && '(' <= data[i] && data[i] <= '/')																			
		{
			EshowD[EshowLen++] = data[i++];
			flag = 1;
		}
		if(flag == 1)			EshowD[EshowLen++] = '?', flag = 0;
	}
	int res = compute(data, len);																		// cmpute the data
	
	EshowD[EshowLen++] = '=';
	EshowD[EshowLen++] = '?';
	int temp = 1, i = 0;
	int tempstore[10];
	while(res != 0)
	{
		tempstore[i++] = res % 10;
		res /= 10;
	}
	while(i>0)
		EshowD[EshowLen++] = (char)(tempstore[--i] + '0');
	EshowD[EshowLen++] = '?';
}


void reshow(void (* p)(int, char))
{
	showState = 0;
	printf("\r\n underlen = %d EshowLen = %d \r\n",underlen,EshowLen);
	for(int i = 0, j = 0; i < EshowLen; i++)
	{
			if(EshowD[i] == '?')
			{
				j++;continue;
			}
			if(j == underlen)	
				p(1, '_');
			p(0, EshowD[i]);
	}
}

int compute(uint8_t* data, int len)
{
	symbol = StackCCreater(); nums = StackNCreater();																				// init the stackChar and stackNum
	for(int i = 0; i < len; i++)
	{
		if(data[i] >= '0' && data[i] <= '9')
		{
			int * temp = handlenum(data, len, i);
			StackPushNum(nums, temp[0]);
			i = temp[1];
		}
		if(i < len && '(' <= data[i] && data[i] <= '/')																			
		{
			if(data[i] == '*' || data[i] == '/')
				{
					if(!IsCEmpty(symbol))
					{
						char c = StackCTop(symbol);
						if(c == '*' || c == '/')
							StackPushNum(nums, calculate());
					}
				}
				if(data[i] == '+' || data[i] == '-')
				{
					if(!IsCEmpty(symbol))
					{
						char c = StackCTop(symbol);
						while(!IsCEmpty(symbol) && c != '(')
						{ 
							StackPushNum(nums, calculate());
							if (!IsCEmpty(symbol))	c = StackCTop(symbol);
							else c = '(';
						}
					}
				}
				if(data[i] == ')')
				{
					StackPushNum(nums, calculate());
					char c = StackCPop(symbol);
					if(c != '(')
						return -1;
				}
				else
					StackPushChar(symbol, data[i]);
		}
	}
	return calculate();
}
